package it.storm.solution;

/**
 * 1886. 判断矩阵经轮转后是否一致
 * https://leetcode-cn.com/problems/determine-whether-matrix-can-be-obtained-by-rotation/
 */
public class Solutions_1886 {
    public static void main(String[] args) {
//        int[][] mat = {{0, 1}, {1, 0}}, target = {{1, 0}, {0, 1}};  // output: true
//        int[][] mat = {{0, 1}, {1, 1}}, target = {{1, 0}, {0, 1}};  // output: false
        int[][] mat = {{0, 0, 0}, {0, 1, 0}, {1, 1, 1}}, target = {{1, 1, 1}, {0, 1, 0}, {0, 0, 0}};  // output: true

        boolean result = findRotation(mat, target);
        System.out.println(result);
    }

    public static boolean findRotation(int[][] mat, int[][] target) {
        // 当前矩阵是否相同
        boolean flag = compareMatrix(mat, target);
        if (flag) {
            return true;
        }
        // 矩阵共 4 种形式，还可翻转 3 次
        for (int i = 0; i < 3; i++) {
            // 旋转一次
            rotation(mat);
            // 是否相同
            flag = compareMatrix(mat, target);
            if (flag) {
                return true;
            }
        }
        return false;
    }

    /**
     * 矩阵顺时钟旋转 90 度：先左-右对角线翻转，后左右翻转
     */
    public static void rotation(int[][] mat) {
        // 左-右对角线翻转
        int len = mat.length;
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < i; j++) {
                int temp = mat[i][j];
                mat[i][j] = mat[j][i];
                mat[j][i] = temp;
            }
        }
        // 左右翻转
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < len / 2; j++) {
                int temp = mat[i][j];
                mat[i][j] = mat[i][len - 1 - j];
                mat[i][len - 1 - j] = temp;
            }
        }
    }

    /**
     * 判断两个矩阵元素是否相同
     */
    public static boolean compareMatrix(int[][] mat, int[][] target) {
        for (int i = 0; i < mat.length; i++) {
            for (int j = 0; j < mat[i].length; j++) {
                if (mat[i][j] != target[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }
}
